package com.sinosoft.perfect.system.license.bean;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

import com.sinosoft.perfect.system._.util.MD5Util;
import com.sinosoft.perfect.system._.util.Producer;
import com.sinosoft.perfect.system.license.vo.License;

public class LicenseContainerBean {

	public final static String NO_LICENSE = "NO_LICENSE";
	
	public final static String READ_ERROR_LICENSE = "READ_ERROR_LICENSE";
	
	public final static String RIGHT_LICENSE = "RIGHT_LICENSE";
	
	public final static String ERROR_LICENSE = "ERROR_LICENSE";
	
	public final static String OUT_LICENSE = "OUT_LICENSE";
	
	public final static String REGISTER_VERSION = "v0.1";
	
	private License license;

	public License getLicense() {
		return license;
	}

	private String licenseStartDecoding;
	private String licenseEndDEcoding;
	
	public String getLicenseStartDecoding() {
		return licenseStartDecoding;
	}
	private void setLicenseStartDecoding(String licenseStartDecoding) {
		this.licenseStartDecoding = licenseStartDecoding;
	}
	public String getLicenseEndDEcoding() {
		return licenseEndDEcoding;
	}
	private void setLicenseEndDEcoding(String licenseEndDEcoding) {
		this.licenseEndDEcoding = licenseEndDEcoding;
	}


	public void setLicense(License license) {
		this.license = license;
		
		if(this.license.getLicenseStart() != null && this.license.getLicenseEnd() != null){
			setLicenseStartDecoding(decodingLicenseBaseOfMine(this.license.getLicenseStart()));
			setLicenseEndDEcoding(decodingLicenseBaseOfMine(this.license.getLicenseEnd()));
		}else{
			setLicenseStartDecoding(null);
			setLicenseEndDEcoding(null);
		}
	}
	
	
	public String getLicenseStatus(){
		if(license == null)
			return LicenseContainerBean.READ_ERROR_LICENSE;
		if(license.getLicenseName() == null || license.getLicenseSerial() == null
				|| "".equals(license.getLicenseName()+"") || "".equals(license.getLicenseSerial()+"")) 
			return LicenseContainerBean.NO_LICENSE;
		if(validateLicenseTimeout())
			return LicenseContainerBean.OUT_LICENSE;
		return LicenseContainerBean.RIGHT_LICENSE;
	}
	
	public String generateNewMechineNumber(){
		String time10 = Producer.generateIdOfTen();
		return time10;
	}
	
	public License validateRegisterLicense(License licenseParam){
		License newLicense = null;
		if(licenseParam != null){
			LicenseSerialInfo serial = validateLicenseSerial(licenseParam.getLicenseName(),licenseParam.getLicenseSerial());
			if(serial != null){
				newLicense = new License();
				newLicense.setLicenseId(license.getLicenseId());
				newLicense.setLicenseMechine(license.getLicenseMechine());
				newLicense.setLicenseName(licenseParam.getLicenseName());
				newLicense.setLicenseSerial(licenseParam.getLicenseSerial());
				newLicense.setLicenseStart(serial.getC_Serial());
				newLicense.setLicenseEnd(encodingLicenseBaseOfMine(initLicenseEndTime(serial.getLicenseStartTime(),serial.getLimit())));
			}
		}
		return newLicense;
	}
	
	private String initLicenseEndTime(String startTime,String limit){
		return ""+((Long.valueOf(startTime) / 1000)+Integer.parseInt(limit) * 24 * 60 * 60 )*1000;
	}
	private String encodingLicenseBaseOfMine(String code){
		return MD5Util.byteToHexString(code.getBytes());
	}
	private String decodingLicenseBaseOfMine(String code){
		return new String(MD5Util.hexStringToByte(code));
	}
	private boolean validateLicenseTimeout(){
		boolean result = true;
		if(System.currentTimeMillis() <= Long.valueOf(decodingLicenseBaseOfMine(license.getLicenseEnd()))){
			result = false;
		}
		return result;
	}
	
	
	private LicenseSerialInfo validateLicenseSerial(String licenseNameParam,String licenseSerialParam){
		LicenseSerialInfo lsi = decoding(licenseNameParam,licenseSerialParam);
		if(lsi != null){
			if(!lsi.getAuthorizationType().equals("0") && !lsi.getAuthorizationType().equals("1"))
				lsi = null;
			if(!lsi.getLicenseName().equals(licenseNameParam))
				lsi = null;
			if(!lsi.getBindingMechine().equals("0") && !lsi.getBindingMechine().equals("1"))
				lsi = null;
			if(lsi.getBindingMechine().equals("1") && !lsi.getLicenseMechine().equals(getLicense().getLicenseMechine())){
				lsi = null;
			}
			if(Integer.valueOf(lsi.getLimit()) <1 ){
				lsi = null;
			}
			if(!lsi.getRegisterVersion().equals(LicenseContainerBean.REGISTER_VERSION)){
				lsi = null;
			}
		}
		
		return lsi;
	}
	
	private LicenseSerialInfo decoding(String licenseNameParam,String licenseSerialParam){
		if(licenseSerialParam.split("&&").length != 3 ){
			return null;
		}			
		DecodingSerial ds = new DecodingSerial(licenseNameParam,licenseSerialParam);
		return ds.getSerial();
	}
	
	/**
	 * 解析序列号
	 * @author gaoyan
	 *
	 */
	private class DecodingSerial{
		
		private String a_Serial;
		private String b_Serial;
		private String c_Serial;
		private String licenseName;
		private String licenseMechine;
		
		public DecodingSerial(String licenseNameParam,String licenseSerialParam){
			if(licenseNameParam == null || licenseSerialParam == null){
				return;
			}
			this.licenseName = licenseNameParam;
			String params[] = licenseSerialParam.split("&&");
			if(params.length == 3){
				this.a_Serial = params[0];
				this.b_Serial = params[1];	
				this.c_Serial = params[2];	
			}
			licenseMechine = getLicense().getLicenseMechine();
		}
		
		public LicenseSerialInfo getSerial() {
			LicenseSerialInfo lsi = null;
			if(!validateEmtpy())return lsi;
			try {
				String decodingASerialStr = decodingASerial();
				if(decodingASerialStr != null){
					String decodingBSerialStr = decodingBSerial();
					if(decodingBSerialStr != null){
						String decodingCSerialStr = decodingCSerial();
						if(decodingCSerialStr != null){
							lsi = new LicenseSerialInfo(decodingASerialStr.split("-"),decodingBSerialStr.split("-")[1],decodingCSerialStr);
							lsi.setSerial(a_Serial, b_Serial, c_Serial);
						}
					}
				}
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				return lsi;
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				return lsi;
			}
			return lsi;
		}
		
		private String decodingASerial() throws NoSuchAlgorithmException, UnsupportedEncodingException{
			String authorizationType ; //1代表正式授权，0代表试用版本授权
			String bindingMechine;//1 绑定 0 不绑定
			if(MD5Util.validPassword(1+"-"+licenseName+"-"+licenseMechine+"-"+1+"-"+REGISTER_VERSION,a_Serial)){
				authorizationType = "1";
				bindingMechine = "1";
			}else
			if(MD5Util.validPassword(0+"-"+licenseName+"-"+licenseMechine+"-"+1+"-"+REGISTER_VERSION,a_Serial)){
				authorizationType = "0";
				bindingMechine = "1";
			}else
			if(MD5Util.validPassword(1+"-"+licenseName+"-"+licenseMechine+"-"+0+"-"+REGISTER_VERSION,a_Serial)){
				authorizationType = "1";
				bindingMechine = "0";
			}else
			if(MD5Util.validPassword(0+"-"+licenseName+"-"+licenseMechine+"-"+0+"-"+REGISTER_VERSION,a_Serial)){
				authorizationType = "0";
				bindingMechine = "0";
			}else
				return null;
			return (authorizationType+"-"+licenseName+"-"+licenseMechine+"-"+bindingMechine+"-"+REGISTER_VERSION);
		}
		
		private String decodingBSerial() throws NoSuchAlgorithmException, UnsupportedEncodingException{
			String BSerial = null;
			for(int i=180;i<2920;i++){
				BSerial = "LIMIT-"+i;
				if(MD5Util.validPassword(BSerial,b_Serial)){
					break;
				}else{
					BSerial = null;
				}
			}
			if(BSerial == null){
				for(int i=0;i<180;i++){
					BSerial = "LIMIT-"+i;
					if(MD5Util.validPassword(BSerial,b_Serial)){
						break;
					}else{
						BSerial = null;
					}
				}				
			}
			return BSerial;
		}
		
		private String decodingCSerial() {
			String BSerial = decodingLicenseBaseOfMine(c_Serial);
			try{
				Long.valueOf(BSerial);
			}catch(NumberFormatException nef){
				return null;
			}
			return BSerial;
		}
		
		private boolean validateEmtpy(){
			boolean result = true;
			if(a_Serial == null || b_Serial == null)
				result = false;
			return result;
		}
		
	}
	
	/**
	 * 序列号信息
	 * @author gaoyan
	 *
	 */
	private class LicenseSerialInfo{
		private String authorizationType ; //1代表正式授权，0代表试用版本授权
		private String licenseName;
		private String licenseMechine;
		private String bindingMechine;//1 绑定 0 不绑定
		private String limit;
		private String registerVersion;//
		private String licenseStartTime;
		private String a_Serial;
		private String b_Serial;
		private String c_Serial;
		
		public LicenseSerialInfo(String [] serials,String limit,String licenseStartTime){
			setAuthorizationType(serials[0]);
			setLicenseName(serials[1]);
			setLicenseMechine(serials[2]);
			setBindingMechine(serials[3]);
			setRegisterVersion(serials[4]);
			setLimit(limit);
			setLicenseStartTime(licenseStartTime);
		}
		
		public void setSerial(String a_Serial,String b_Serial,String c_Serial){
			setA_Serial(a_Serial);
			setB_Serial(b_Serial);
			setC_Serial(c_Serial);
		}
		
		public String getAuthorizationType() {
			return authorizationType;
		}
		public void setAuthorizationType(String authorizationType) {
			this.authorizationType = authorizationType;
		}
		public String getLicenseName() {
			return licenseName;
		}
		public void setLicenseName(String licenseName) {
			this.licenseName = licenseName;
		}
		public String getLicenseMechine() {
			return licenseMechine;
		}
		public void setLicenseMechine(String licenseMechine) {
			this.licenseMechine = licenseMechine;
		}
		public String getBindingMechine() {
			return bindingMechine;
		}
		public void setBindingMechine(String bindingMechine) {
			this.bindingMechine = bindingMechine;
		}
		public String getLimit() {
			return limit;
		}
		public void setLimit(String limit) {
			this.limit = limit;
		}
		public String getRegisterVersion() {
			return registerVersion;
		}
		public void setRegisterVersion(String registerVersion) {
			this.registerVersion = registerVersion;
		}
		public String getLicenseStartTime() {
			return licenseStartTime;
		}
		public void setLicenseStartTime(String licenseStartTime) {
			this.licenseStartTime = licenseStartTime;
		}
		@SuppressWarnings("unused")
		public String getA_Serial() {
			return a_Serial;
		}
		public void setA_Serial(String a_Serial) {
			this.a_Serial = a_Serial;
		}
		@SuppressWarnings("unused")
		public String getB_Serial() {
			return b_Serial;
		}
		public void setB_Serial(String b_Serial) {
			this.b_Serial = b_Serial;
		}
		public String getC_Serial() {
			return c_Serial;
		}
		public void setC_Serial(String c_Serial) {
			this.c_Serial = c_Serial;
		}
		
	}
}
